package com.wxzz.elearning.gateway.filter.pre;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import com.wxzz.elearning.common.constants.RedisConstants;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Set;

@Component
public class TokenGlobalFilter implements GlobalFilter {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 白名单直接放行
     */
    private static final Set<String> WHITE_STR_LIST = Sets.newHashSet();

    static {
        //swagger
        WHITE_STR_LIST.add("swagger");
        WHITE_STR_LIST.add("api-docs");
        WHITE_STR_LIST.add("doc.html");
        //todo 测试给予权限
        //WHITE_STR_LIST.add("/auth/updateAdminUserRole");
        //登录
        WHITE_STR_LIST.add("wxLogin");
        WHITE_STR_LIST.add("adminUserLogin");
        //首页接口
        WHITE_STR_LIST.add("wxListDocent");
        WHITE_STR_LIST.add("listCurriculumByCategory");
        WHITE_STR_LIST.add("listCurriculumCategory");
        WHITE_STR_LIST.add("listAllLivetelecastCategory");
        WHITE_STR_LIST.add("listAllLivetelecastCategorySecond");
        WHITE_STR_LIST.add("wxListPlatformLivetelecast");
        WHITE_STR_LIST.add("listActivityCategory");
        WHITE_STR_LIST.add("listActivity");
        WHITE_STR_LIST.add("wxListBannerManage");
        WHITE_STR_LIST.add("selectOnePlatformParam");
        WHITE_STR_LIST.add("selectPlatformParamVo");
        WHITE_STR_LIST.add("selectPlatformParamPhoneVo");
        WHITE_STR_LIST.add("listEnterprise");
        WHITE_STR_LIST.add("queryQuestionsAnswersList");
        WHITE_STR_LIST.add("sendCode");
        WHITE_STR_LIST.add("updatePassword");

        //支付接口回调
        WHITE_STR_LIST.add("notifyUrl");
        // 华为云直播录播回调
        WHITE_STR_LIST.add("liveRecordCallback");
        // 华为云直播开播状态回调
        WHITE_STR_LIST.add("livePushCallback");
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        for (String s : WHITE_STR_LIST) {
            if (exchange.getRequest().getURI().getPath().contains(s)) {
                return chain.filter(exchange);
            }
        }
        ServerHttpResponse response = exchange.getResponse();
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if (StringUtils.isBlank(token) || !redisTemplate.hasKey(token) || StringUtils.isBlank(redisTemplate.opsForValue().get(token))) {
            String msg = "{\n" +
                    "  \"code\": \"401\",\n" +
                    "  \"message\": \"please login\"\n" +
                    "}";
            DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
            return response.writeWith(Mono.just(buffer));
        }
        //校验小程序端
        String path = exchange.getRequest().getURI().getPath();
        if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(redisTemplate.opsForValue().get(token)) && path.contains("wx-") && token.contains(RedisConstants.WX_TOKEN)) {
            return chain.filter(exchange);
        }
        //总后台/企业后台token
        if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(redisTemplate.opsForValue().get(token)) && token.contains(RedisConstants.ADMIN_TOKEN)) {
            String s = redisTemplate.opsForValue().get(token);
            JSONObject jsonObject = JSONObject.parseObject(s);
            String uris = redisTemplate.opsForValue().get(RedisConstants.USER_PERMISSION + jsonObject.getLong("id"));
            List<String> list = JSONObject.parseObject(uris, List.class);

            //权限集合
//            if (StringUtils.isNotBlank(uris) && list.contains(path)) {
//                return chain.filter(exchange);
//            } else {
//                String msg = "{\n" +
//                        "  \"code\": \"403\",\n" +
//                        "  \"message\": \"没有权限\"\n" +
//                        "}";
//                DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
//                return response.writeWith(Mono.just(buffer));
//            }
        }
        //校验讲师端token
//        if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(redisTemplate.opsForValue().get(token)) && token.contains(RedisConstants.DOCENT_TOKEN)) {
//            JSONObject jsonObject = JSONObject.parseObject(redisTemplate.opsForValue().get(token));
//            if (jsonObject.getLong("docentId") != null) {
//                return chain.filter(exchange);
//            } else {
//                String msg = "{\n" +
//                        "  \"code\": \"403\",\n" +
//                        "  \"message\": \"该账号未绑定讲师\"\n" +
//                        "}";
//                DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
//                return response.writeWith(Mono.just(buffer));
//            }
//        }
//
//        String msg = "{\n" +
//                "  \"code\": \"401\",\n" +
//                "  \"message\": \"请登录\"\n" +
//                "}";
//        DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
//        return response.writeWith(Mono.just(buffer));
        //todo 开发环境放行
        return chain.filter(exchange);
    }
}
